from django.views.generic.base import View
from django.shortcuts import render
from django.http import JsonResponse
from django.core import serializers
from django.db.models import Avg, Max, Min, Count, Sum
from utils.mixin_utils import LoginRequiredMixin
from systems.models import Dept, Role, Menu, MenuButton


class ListView(LoginRequiredMixin, View):
    def get(self, request):
        v_objs = Role.objects.filter(is_delete=0).values('id', 'name', 'sort')\
            .annotate(user_count=Count('userprofile__role'))\
            .order_by('sort')
        return render(request, 'systems/permission.html', {'p_objs': v_objs,
                                                           'p_depts': get_dept(),
                                                           'p_menus': get_menu_button()})


class DetailView(LoginRequiredMixin, View):
    def get(self, request):
        role = Role.objects.get(id=request.GET.get('id'))
        depts = role.dept.all()
        menus = role.menu.all()
        buttons = role.permission.all()
        return JsonResponse({'code': '200',
                             'h_obj': role.to_json(),
                             'h_depts': serializers.serialize("json", depts),
                             'h_menus': serializers.serialize("json", menus),
                             'h_buttons': serializers.serialize("json", buttons)})


class SaveDataView(LoginRequiredMixin, View):
    def post(self, request):
        v_role_id = request.POST.get('role')
        if v_role_id is None or v_role_id == '':
            return JsonResponse({'code': '444', 'msg': '请选择角色'})
        v_data_range = request.POST.get('data_range')
        if v_data_range is None or v_data_range == '':
            return JsonResponse({'code': '444', 'msg': '请选择数据授权'})

        try:
            role = Role.objects.get(id=int(v_role_id))
            role.data_range = v_data_range
            role.save()
            # 处理自定义数据权限
            role.dept.clear()
            if v_data_range == '4':
                depts = list(map(int, request.POST.getlist('depts[]')))
                if len(depts) == 0:
                    return JsonResponse({'code': '444', 'msg': '请选择部门'})
                role.dept.add(*depts)
            return JsonResponse({'code': '200', 'msg': '保存数据授权成功'})
        except:
            return JsonResponse({'code': '444', 'msg': '保存数据授权失败'})


class SaveMenuView(LoginRequiredMixin, View):
    def post(self, request):
        v_role_id = request.POST.get('role')
        if v_role_id is None or v_role_id == '':
            return JsonResponse({'code': '444', 'msg': '请选择角色'})

        try:
            role = Role.objects.get(id=int(v_role_id))
            menus = list(map(int, request.POST.getlist('menus[]')))
            role.menu.clear()
            role.menu.add(*menus)

            buttons = list(map(int, request.POST.getlist('buttons[]')))
            role.permission.clear()
            role.permission.add(*buttons)
            return JsonResponse({'code': '200', 'msg': '保存菜单授权成功'})
        except:
            return JsonResponse({'code': '444', 'msg': '保存菜单授权失败'})


def get_dept():
    """
    获取授权部门表格
    :return: 返回树形的部门结构HTML
    """
    dept_tree = ''
    depts = Dept.objects.filter(is_delete=0)

    def get_child(i_dept, i_p_l):
        """递归获取树的子节点"""
        exist_child = False
        child_tree = ''
        for dept1 in depts:
            if dept1.parent is not None and dept1.parent == i_dept:
                exist_child = True
                child_tree += get_child(dept1, i_p_l + 30)

        if exist_child:
            parent_tree = f'<tr>'
            parent_tree += f'<td style="padding-left: {i_p_l}px;">'
            parent_tree += f'<label class="lyear-checkbox checkbox-primary">'
            parent_tree += f'<input name="depts[]" type="checkbox" class="checkbox-parent" value="{i_dept.id}" id="dept{i_dept.id}">'
            parent_tree += f'<span> {i_dept.name}</span>'
            parent_tree += f'</label>'
            parent_tree += f'</td>'
            parent_tree += f'</tr>'
            parent_tree += child_tree
            return parent_tree
        else:
            child_tree = f'<tr>'
            child_tree += f'<td style="padding-left: {i_p_l}px;">'
            child_tree += f'<label class="lyear-checkbox checkbox-primary">'
            child_tree += f'<input name="depts[]" type="checkbox" class="checkbox-parent checkbox-child" value="{i_dept.id}" id="dept{i_dept.id}">'
            child_tree += f'<span> {i_dept.name}</span>'
            child_tree += f'</label>'
            child_tree += f'</td>'
            child_tree += f'</tr>'
            return child_tree

    for dept in depts:
        if dept.parent is None:
            dept_tree += get_child(dept, 3)

    return dept_tree


def get_menu_button():
    """
    获取授权菜单按钮表格
    YPN 2021-09-19 Create
    :return: 返回树形的菜单结构HTML
    """
    menu_tree = ''
    menus = Menu.objects.filter(is_delete=0)
    menu_buttons = MenuButton.objects.filter(is_delete=0)

    def get_child(i_menu, i_p_l, i_parent_id):
        """递归获取树的子节点"""
        exist_child = False
        child_tree = ''
        for menu1 in menus:
            if menu1.parent is not None and menu1.parent == i_menu:
                exist_child = True
                child_tree += get_child(menu1, i_p_l + 30, f'{i_parent_id}-{menu1.id}')

        if exist_child:
            parent_tree = f'<tr>'
            parent_tree += f'<td style="padding-left: {i_p_l}px;">'
            parent_tree += f'<label class="lyear-checkbox checkbox-primary">'
            parent_tree += f'<input name="menus[]" type="checkbox" class="checkbox-parent" dataid="id-{i_parent_id}" value="{i_menu.id}" id="menu{i_menu.id}">'
            parent_tree += f'<span> {i_menu.name}</span>'
            parent_tree += f'</label>'
            parent_tree += f'</td>'
            parent_tree += f'</tr>'
            parent_tree += child_tree
            return parent_tree
        else:
            child_tree = f'<tr>'
            child_tree += f'<td style="padding-left: {i_p_l}px;">'
            child_tree += f'<label class="lyear-checkbox checkbox-primary">'
            child_tree += f'<input name="menus[]" type="checkbox" class="checkbox-parent checkbox-child" dataid="id-{i_parent_id}" value="{i_menu.id}" id="menu{i_menu.id}">'
            child_tree += f'<span> {i_menu.name}</span>'
            child_tree += f'</label>'
            child_tree += f'</td>'
            child_tree += f'</tr>'

            exist_button = False
            button_tree = f'<tr>'
            button_tree += f'<td style="padding-left: {i_p_l + 30}px;">'
            for button in menu_buttons:
                if button.menu == i_menu:
                    exist_button = True
                    button_tree += f'<label class="lyear-checkbox checkbox-primary checkbox-inline">'
                    button_tree += f'<input name="buttons[]" type="checkbox" class="checkbox-child" dataid="id-{i_parent_id}-{button.id}" value="{button.id}" id="button{button.id}">'
                    button_tree += f'<span> {button.name}</span>'
                    button_tree += f'</label>'
            button_tree += f'</td>'
            button_tree += f'</tr>'
            if exist_button:
                return child_tree + button_tree
            else:
                return child_tree

    for menu in menus:
        if menu.parent is None:
            menu_tree += get_child(menu, 3, menu.id)

    return menu_tree
